#include "oled.h"

u8g2_t u8g2;

struct bflb_device_s *i2c0;       //i2c0外设句柄

struct bflb_i2c_msg_s msgs;			//I2C发送数据结构体数组

//初始化I2C引脚
void I2c0_gpio_init(void)                 
{
    struct bflb_device_s* gpio;

    gpio = bflb_device_get_by_name("gpio");
    /* I2C0_SCL */
    bflb_gpio_init(gpio, GPIO_PIN_0, GPIO_FUNC_I2C0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
    /* I2C0_SDA */
    bflb_gpio_init(gpio, GPIO_PIN_1, GPIO_FUNC_I2C0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
}

//初始化I2C
void I2c0_init(void) 
{
	I2c0_gpio_init();
	i2c0 = bflb_device_get_by_name("i2c0");

	//I2C初始化
	bflb_i2c_init(i2c0, 400000);
}

uint8_t u8x8_byte_hw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
    /* u8g2/u8x8 will never send more than 32 bytes between START_TRANSFER and END_TRANSFER */
    static uint8_t buffer[128];
    static uint8_t buf_idx;
    uint8_t *data;
    switch (msg)
    {
    case U8X8_MSG_BYTE_INIT:
    {
        /*初始化I2C*/
		I2c0_init();
    }
    break;
 
    case U8X8_MSG_BYTE_START_TRANSFER:
    {
        buf_idx = 0;
    }
    break;
 
    case U8X8_MSG_BYTE_SEND:
    {
        data = (uint8_t *)arg_ptr;
 
        while (arg_int > 0)
        {
            buffer[buf_idx++] = *data;
            data++;
            arg_int--;
        }
    }
    break;
 
    case U8X8_MSG_BYTE_END_TRANSFER:
    {
		/*I2C发送数据*/
		msgs.addr = OLED_ADDRESS;
		msgs.buffer=buffer;
		msgs.flags=0;
		msgs.length= buf_idx;
		bflb_i2c_transfer(i2c0, &msgs, 1);
    }
    break;
 
    // case U8X8_MSG_BYTE_SET_DC:
    //     break;
 
    default:
        return 0;
    }
 
    return 1;
}
 
 //U8G2自带模拟时序回调函数，硬件I2Cb不需要，直接全部注释
uint8_t u8x8_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
// 	 switch (msg)
// 	 {
//    case U8X8_MSG_DELAY_100NANO: // delay arg_int * 100 nano seconds
//        __NOP();
//        break;
//    case U8X8_MSG_DELAY_10MICRO: // delay arg_int * 10 micro seconds
//        for (uint16_t n = 0; n < 320; n++)
//        {
//            __NOP();
//        }
//        break;
// 	  case U8X8_MSG_DELAY_MILLI: // delay arg_int * 1 milli second
// 				bflb_mtimer_delay_ms(1);
// 		  break;
//    case U8X8_MSG_DELAY_I2C: // arg_int is the I2C speed in 100KHz, e.g. 4 = 400 KHz   
//        break;                    // arg_int=1: delay by 5us, arg_int = 4: delay by 1.25us
//    case U8X8_MSG_GPIO_I2C_CLOCK: // arg_int=0: Output low at I2C clock pin
//        break;                    // arg_int=1: Input dir with pullup high for I2C clock pin
//    case U8X8_MSG_GPIO_I2C_DATA:  // arg_int=0: Output low at I2C data pin
//        break;                    // arg_int=1: Input dir with pullup high for I2C data pin
//    case U8X8_MSG_GPIO_MENU_SELECT:
//        u8x8_SetGPIOResult(u8x8, /* get menu select pin state */ 0);
//        break;
//    case U8X8_MSG_GPIO_MENU_NEXT:
//        u8x8_SetGPIOResult(u8x8, /* get menu next pin state */ 0);
//        break;
//    case U8X8_MSG_GPIO_MENU_PREV:
//        u8x8_SetGPIOResult(u8x8, /* get menu prev pin state */ 0);
//        break;
//    case U8X8_MSG_GPIO_MENU_HOME:
//        u8x8_SetGPIOResult(u8x8, /* get menu home pin state */ 0);
//        break;
//    default:
//        u8x8_SetGPIOResult(u8x8, 1); // default return value
//        break;
//	 }
    return 1;
}

//OLED初始化函数
void OLED_Init(void)
{
	u8g2_Setup_ssd1306_i2c_128x64_noname_f(&u8g2, U8G2_R0, u8x8_byte_hw_i2c, u8x8_gpio_and_delay); 
	u8g2_InitDisplay(&u8g2);
	u8g2_SetPowerSave(&u8g2,0);
	u8g2_ClearBuffer(&u8g2);
}
